package purgehelper.custom.controls;

import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceAdapter;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.JList;
import purgehelper.dnd.FileTransferHandler;
import purgehelper.dnd.FileTransferable;

/**
 * Drop files or folders into the Drop Box to be queued up for processing. Drag
 * files or folders out of the box to open up on the OS. Double click to resend
 * the request.
 * @author pborrego
 */
public class DropBox extends JList implements DragGestureListener {

    public DropBox() {
        super();

        this.listmodel = new DropBoxModel();
        this.listmodel.clear();
        this.setModel(this.listmodel);
        this.setDragEnabled(true);
        this.setTransferHandler(new FileTransferHandler());

        this.registerListeners();
    }

    private void registerListeners() {
         this.addMouseListener(new InnerMouse(this));
         this.dt = new DropTarget(this, new InnerDropTarget(this.listmodel));

//         DragSource ds = DragSource.getDefaultDragSource();
//         ds.addDragSourceListener(new InnerDragSource(this));

        DragGestureRecognizer dgr = DragSource.getDefaultDragSource().
                createDefaultDragGestureRecognizer(
                    this, DnDConstants.ACTION_COPY, this
               );

    }

    public void dragGestureRecognized(DragGestureEvent dge) {
        System.out.println("Drag Gesture Recognized!");
        dge.startDrag(null, new FileTransferable(new ArrayList<File>()), new InnerDragSource(this));
    }

    private class InnerDragSource extends DragSourceAdapter {
        private final JList list;

        public InnerDragSource(JList l) {
            this.list = l;
        }

        @Override
        public void dragDropEnd(DragSourceDropEvent dsde) {
            // This method is invoked to signify that the Drag and Drop operation is complete.
            System.out.println("InnerDragSource: drag drop ended.");
        }
    }
    
    private class InnerDropTarget extends DropTargetAdapter {
        private final DropBoxModel listmodel;

        public InnerDropTarget(DropBoxModel l) {
            this.listmodel = l;
        }

        public void drop(DropTargetDropEvent dtde) {
            int action = dtde.getDropAction();
            dtde.acceptDrop(action);
            DropBoxLocation dbl;

            try {
                Transferable data = dtde.getTransferable();
                if (data.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
                    List<File> files = (List<File>) data.getTransferData(
                            DataFlavor.javaFileListFlavor);
                    for (File file : files) {

                        dbl = new DropBoxLocation(file, "");
                        this.listmodel.addElement(dbl);
                    }
                }
            } catch (UnsupportedFlavorException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                dtde.dropComplete(true);
                System.out.println("Drop COMPLETE");
            }
        }
    }

    private class InnerMouse extends MouseAdapter {
        private final JList list;

        public InnerMouse(JList l) {
            this.list = l;
        }

        @Override
        public void mouseClicked(MouseEvent e) {
            if(e.getClickCount() == 2) {
                int index = list.locationToIndex(e.getPoint());
                System.out.println("Double click on index: " + index);
            }
        }
    }

    public Icon getDirectory() {
        return directory;
    }

    public void setDirectory(Icon directory) {
        this.directory = directory;
    }

    public Icon getFile() {
        return file;
    }

    public void setFile(Icon file) {
        this.file = file;
    }



    private DropBoxModel listmodel;
    private DropTarget dt;
    private DragSource ds;
    private Icon directory, file;
}
